﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Koopakiller.Numerics.Resources;

namespace System.Collections.Generic
{
    /// <summary>
    /// Contains extensions for the <see cref="System.Collections.Generic"/> namespace.
    /// </summary>
    public static class Extensions_Generic
    {
        /// <summary>
        /// Create a deep copy of a dictionary.
        /// </summary>
        /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
        /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
        /// <param name="dictionary">The dictionary to copy.</param>
        /// <param name="keyCopier">A function to copy a key.</param>
        /// <param name="valueCopier">A function to copy a value.</param>
        /// <returns>A new dictionary with the keys and values from <paramref name="dictionary"/>.</returns>
        public static Dictionary<TKey, TValue> Copy<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, Func<TKey, TKey> keyCopier, Func<TValue, TValue> valueCopier)
        {
            if (dictionary == null)
                throw ExceptionHelper.GetArgumentNull("dictionary", "extension");
            return dictionary.ToDictionary(x => keyCopier(x.Key), x => valueCopier(x.Value));
        }

        /// <summary>
        /// Removes the items at the specific indexes.
        /// </summary>
        /// <typeparam name="T">The type of elements in the list.</typeparam>
        /// <param name="source">The list to change.</param>
        /// <param name="itemIndices">The indexes of the items to remove.</param>
        public static void RemoveItemsAt<T>(this IList<T> source, params int[] itemIndices)
        {
            if (source == null)
                throw ExceptionHelper.GetArgumentNull("source", "extension", "");
            if (itemIndices == null)
                throw ExceptionHelper.GetArgumentNull("itemIndices", "value", "");

            foreach (var itemIndex in itemIndices.OrderByDescending(x => x))
                source.RemoveAt(itemIndex);
        }
    }
}
